package Util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

public class AMUtil {

	public static double entropia(ArrayList<String[]> base, int feature){
		double entropia = 0;
		
		ArrayList<Double> histograma = histograma(base, feature);
		
		for (Double pAmostra : histograma) {
			entropia += pAmostra * (Math.log(pAmostra)/Math.log(2));
		}
		
		return - entropia;
	}
	
//	public static double infMutuaCondicional(ArrayList<String[]> base, int feature1, int feature2 ){
//		
//		ArrayList<String> histF1 = histogramaKeys(base, feature1); 
//		ArrayList<String> histF2 = histogramaKeys(base, feature2);
//		
//		double infConj = 0;
//		
//		for (String a1 : histF1) {
//			for (String a2 : histF2) {
//				double pxy = probabilidadeConjunta(base, feature1, a1, feature2, a2);
//				if(pxy != 0){
//					double px = probabilidade(base, feature1, a1);
//					double py = probabilidade(base, feature2, a2);
//					double temp= pxy * Math.log( pxy / (px * py) )/Math.log(2);
//					infConj += temp;
//				}
//			}
//		}
//		
//		return infConj;
//	}
	
	
//	public static double infMutuaCondicional(ArrayList<String[]> base, int feature1, int feature2, int featureCondicao ){
//		return 0;
//	}
//	
	
	public static double probabilidadeConjuntaCondicional(ArrayList<String[]> base, int feature1, String value1, int feature2, String value2, int featureCondicao, String valueCondicao ){
		int contadorCondicao = 0;
		int contadorProb = 0;
		for (String[] linha : base) {
			if(linha[featureCondicao].equals(valueCondicao)){
				contadorCondicao++;
				if(linha[feature1].equals(value1)
						&& linha[feature2].equals(value2)){
					
					contadorProb++;
				}
			}
					
		}
	
		return contadorProb/(double)contadorCondicao;
	}
	
	public static double probabilidadeCondicional(ArrayList<String[]> base, int feature1, String value1, int featureCondicao, String valueCondicao ){
		int contadorCondicao = 0;
		int contadorProb = 0;
		for (String[] linha : base) {
			if(linha[featureCondicao].equals(valueCondicao)){
				contadorCondicao++;
				if(linha[feature1].equals(value1)){
					contadorProb++;
				}
			}
					
		}
	
		return contadorProb/(double)contadorCondicao;
	}

	public static double probabilidade(ArrayList<String[]> base, int feature1, String value1){
		int contador = 0;
		for (String[] linha : base) {
			if(linha[feature1].equals(value1)){
				contador++;
			}
		}
	
		return contador/(double)base.size();
	}
	
	public static double probabilidadeConjunta(ArrayList<String[]> base, int feature1, String value1, int feature2, String value2){
		int contador = 0;
		for (String[] linha : base) {
			if(linha[feature1].equals(value1)
					&& linha[feature2].equals(value2)){
				
				contador++;
			}
		}
	
		return contador/(double)base.size();
	}
	
	public static double probabilidadeConjunta(ArrayList<String[]> base, int feature1, String value1, int feature2, String value2, int feature3, String value3 ){
		int contador = 0;
		for (String[] linha : base) {
			if(linha[feature1].equals(value1)
					&& linha[feature2].equals(value2)
					&& linha[feature3].equals(value3)){
				
				contador++;
			}
		}
	
		return contador/(double)base.size();
	}
	
	public static ArrayList<Double> histograma(ArrayList<String[]> base, int feature){

		HashMap<String, Integer> hash = new HashMap<>();
		
		for (String[] linha : base) {
			String s = linha[feature];
			if(hash.containsKey(s)){
				hash.put(s, hash.get(s) + 1);
			} else {
				hash.put(s, 1);
			}
			
		}
		
		Collection<Integer> list = hash.values();
		ArrayList<Double> hist = new ArrayList<>();
 		for (Integer integer : list) {
			hist.add(integer/(double)base.size());
		}
 		hash.clear();
 		hash = null;
 		System.gc();
		return hist;
	}
	
	public static ArrayList<String> histogramaKeys(ArrayList<String[]> base, int feature){

		HashMap<String, Integer> hash = new HashMap<>();
		
		for (String[] linha : base) {
			String s = linha[feature];
			if(hash.containsKey(s)){
				hash.put(s, hash.get(s) + 1);
			} else {
				hash.put(s, 1);
			}
			
		}
		
		Collection<String> list = hash.keySet();
		ArrayList<String> hist = new ArrayList<>();
 		for (String s : list) {
			hist.add(s);
		}
 		hash.clear();
 		hash = null;
 		System.gc();
		return hist;
	}
}
